package com.right.handler;

import com.right.command.CsCommand;
import com.right.db.Bicycle;
import com.right.db.BicycleDockSite;
import com.right.factory.NodeStatus;
import com.right.mapper.BicycleDockSiteMapper;
import com.right.mapper.BicycleMapper;
import com.right.mapper.CommonMapper;
import com.right.util.push.PushUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <pre>
 *     @author : pillar
 *     e-mail : 347637454@qq.com
 *     time   : 2019/1/3 10:23
 *     desc   :
 *     version: 1.0
 * </pre>
 */
@Slf4j
public class LockHandler implements PackageHandler{
    private final BicycleMapper bicycleMapper;
    private final BicycleDockSiteMapper bicycleDockSiteMapper;
    private final CommonMapper commonMapper;

    public LockHandler(BicycleMapper bicycleMapper, BicycleDockSiteMapper bicycleDockSiteMapper, CommonMapper commonMapper) {
        this.bicycleMapper = bicycleMapper;
        this.bicycleDockSiteMapper = bicycleDockSiteMapper;
        this.commonMapper = commonMapper;
    }

    @Override
    public boolean applies(List<String> dataList) {
        return CsCommand.LOCK.equals(dataList.get(0));
    }

    @Override
    public boolean handleMessage(ChannelHandlerContext ctx, List<String> dataList) {
        String lockNo = ctx.channel().attr(NodeStatus.LOCK_NO).get();
        log.info("锁车指令上送,lockNo={}",lockNo);
        int putType ;
        Example o = new Example(Bicycle.class);
        o.createCriteria().andEqualTo("lockNo",lockNo);
        o.selectProperties("id","bicycleNo","operatorId","bicycleStatus","bicycleDocksiteId","bicycleDocksiteNo");
        List<Bicycle> list = bicycleMapper.selectByExample(o);
        if (list.size() > 0){
            Bicycle r = list.get(0);
            Byte bicycleStatus = r.getBicycleStatus();
            if(bicycleStatus != 2 && bicycleStatus != 3 && bicycleStatus != 5 && bicycleStatus != 6 && bicycleStatus != 7  && bicycleStatus != 9){
                log.info("自行车状态不正确,bikeNo={}",r.getBicycleNo());
                return false;
            }

            o = new Example(BicycleDockSite.class);
            o.createCriteria().andEqualTo("docksiteNo",r.getBicycleDocksiteNo());
            o.selectProperties("type");
            List<BicycleDockSite> bds = bicycleDockSiteMapper.selectByExample(o);
            Integer dockSiteType =  bds.get(0).getType();
            /*校验租车记录是否存在*/
            Map<String,Object> rentMap = commonMapper.selectRentRecord(r.getBicycleNo(),r.getOperatorId());
            if (Objects.isNull(rentMap)){
                log.info("未找到租车记录,bikeNo={}",r.getBicycleNo());
                return false;
            }
            if(bicycleStatus == 2 || bicycleStatus == 5){
                String rentTimeStr = (String) rentMap.get("datetime");
                Long rentTime =Long.parseLong(rentTimeStr);
               Map<String,Object> tempStopMap =  commonMapper.selectTempStop(r.getId(),(Long)rentMap.get("id"));
                if (!Objects.isNull(tempStopMap)){
                    int tempTime = (Integer) tempStopMap.get("datetime");
                    Date nowTime = (Date) tempStopMap.get("nowTime");
                    /*不大于1分钟认为是临停*/
                    if (2 >= tempTime) {
                        if (bicycleStatus == 5) {
                            commonMapper.updateBicycleStatus(5, nowTime, r.getId());
                        } else {
                            commonMapper.updateBicycleStatus(8, nowTime, r.getId());
                        }
                        commonMapper.updateTempStopStatus(2, nowTime, (Long) tempStopMap.get("id"));
                        putType = 21;
                        goToTuiPush((String) rentMap.get("rider_id"),putType);
                    }

                }else {
                    Date nowTime = new Date();
                    Map<String, Object> accountMap = commonMapper.selectRideAccount(1,(String) rentMap.get("rider_id"));
                    /*余额*/
                    BigDecimal initAmt = (BigDecimal) accountMap.get("balance");
                    String accountId = (String)accountMap.get("id");
                    accountMap = commonMapper.selectRideAccount(2,(String) rentMap.get("rider_id"));
                    /*积分*/
                    BigDecimal initScore = (BigDecimal) accountMap.get("balance");

                    Map<String,Object> chargeMap = commonMapper.selectCharge(r.getOperatorId());

                    BigDecimal timeCharge = (BigDecimal) chargeMap.get("time_charge");
                    BigDecimal maxCharge = (BigDecimal) chargeMap.get("max_charge");

                    double fTmpAmt = (Math.ceil((rentTime % 240000 - 10000) / 10000f) < 0) ? 0 : Math.ceil((rentTime % 240000 - 10000) / 10000f);
                    double f1 = (rentTime / 240000) * maxCharge.doubleValue();
                    double f2 = (fTmpAmt * timeCharge.doubleValue()>= maxCharge.doubleValue()) ? maxCharge.doubleValue() : (fTmpAmt * timeCharge.doubleValue());
                    double fAmt = f1 + f2;
                    Long times =(rentTime/10000)*60+(rentTime%10000)/100+((rentTime%10000)%100>0?1:0);
                    if (1 == dockSiteType){
                        commonMapper.updateBicycleDockSite(nowTime,r.getBicycleDocksiteNo());
                        commonMapper.updateBicycleRent(nowTime,times.intValue(),fAmt,nowTime,r.getBicycleDocksiteNo(),r.getOperatorId(), r.getBicycleDocksiteId(),r.getBicycleNo(),(String)rentMap.get("rider_id"));
                        commonMapper.updateBicycle(r.getBicycleNo(),lockNo,r.getOperatorId());
                        commonMapper.insertA05Consume((String)rentMap.get("rider_id"),accountId,String.valueOf(rentMap.get("id")),new BigDecimal(fAmt),new BigDecimal(fAmt),initAmt,initAmt.subtract(new BigDecimal(fAmt)),nowTime,new BigDecimal(fAmt),initScore,initScore.add(new BigDecimal(fAmt)),nowTime,nowTime,r.getOperatorId());
                    }else if (2 == dockSiteType){
                        commonMapper.updateBicycleDockSiteTwo(nowTime,r.getBicycleDocksiteNo());
                        commonMapper.updateBicycleRent(nowTime,times.intValue(),fAmt,nowTime,r.getBicycleDocksiteNo(),r.getOperatorId(),r.getBicycleDocksiteId(),r.getBicycleNo(),(String)rentMap.get("rider_id"));
                        commonMapper.updateBicycle(r.getBicycleNo(),lockNo,r.getOperatorId());
                        commonMapper.insertA05Consume((String)rentMap.get("rider_id"),accountId, String.valueOf(rentMap.get("id")),new BigDecimal(fAmt),new BigDecimal(fAmt),initAmt,initAmt.subtract(new BigDecimal(fAmt)),nowTime,new BigDecimal(fAmt),initScore,initScore.add(new BigDecimal(fAmt)),nowTime,nowTime,r.getOperatorId());
                    }

                    //获取ride_grand_total信息
                    int count = commonMapper.selectRideGrandTotalCountByRiderId((String)rentMap.get("rider_id"));

                    if (count==0){
                        commonMapper.insertRideGrandTotal((String)rentMap.get("rider_id"),times.intValue(),new BigDecimal(fAmt),nowTime,nowTime);
                    }else{
                        commonMapper.updateRideGrandTotal(times.intValue(),new BigDecimal(fAmt),nowTime,(String)rentMap.get("rider_id"));
                    }

                    if (times.intValue() <= 2){
                        commonMapper.insertBicycleEnterLend(r.getBicycleNo(),(String)rentMap.get("rider_id"),(String)rentMap.get("bicycle_docksite_id_rent"),r.getBicycleDocksiteNo(),nowTime,String.valueOf(rentMap.get("id")));
                    }

                    commonMapper.updateA02AccountYuE(new BigDecimal(fAmt),nowTime,(String)rentMap.get("rider_id"));
                    commonMapper.updateA02AccountJiFen(new BigDecimal(fAmt),nowTime,(String)rentMap.get("rider_id"));

                    if (5 ==r.getBicycleStatus()){
                        commonMapper.updateB30Faultproblem(String.valueOf(rentMap.get("id")));
                    }
                    putType = 3;
                    goToTuiPush((String) rentMap.get("rider_id"),putType);
                }

            }else {
                if (r.getBicycleStatus()==9){
                    commonMapper.updateBicycleDispatchSheetMessage((String)rentMap.get("bicycle_docksite_id_rent"),r.getId());
                }
                //是不是新站点
                //获取自行车号，运营商id，自行车状态
                if (dockSiteType==1){
                    commonMapper.updateBicycleDockSite(new Date(),r.getBicycleDocksiteNo());
                }else {
                    commonMapper.updateBicycleDockSiteTwo(new Date(),r.getBicycleDocksiteNo());
                }
                commonMapper.updateBicycleTwo(r.getBicycleNo(),r.getLockNo(),r.getOperatorId());
               int count =  commonMapper.selectM06unlockingCount(r.getBicycleNo());
               if (count > 0){
                   commonMapper.updateM06unlocking(r.getBicycleDocksiteNo(),r.getBicycleNo());
               }
            }
            return false;
        }
        log.info("未找到锁信息={}",lockNo);
        return false;
    }
    
    //增加推送消息
    //获取设备信息
    private void goToTuiPush(String riderId,Integer putType) {
        int count = commonMapper.selectPdaUseronlineCountByRiderId(riderId);
        if (count==1){
            Map<String, Object> pdaUseronlineMap = commonMapper.selectPdaUseronlineByRiderId(riderId);
            //deviceId 设备id,deviceType设备类型
            String deviceId =(String) pdaUseronlineMap.get("deviceid");
            Integer deviceType = (Integer)pdaUseronlineMap.get("device_type");
            if (putType==21){
                PushUtil.pushToSingle(deviceId, deviceType,"临停锁车成功","关锁",0,21);
            }else if (putType==3){
                PushUtil.pushToSingle(deviceId, deviceType,"还车成功","关锁",0,3);
            }
        }
    }
}
